package com.tiance.demo.service.mysql.analyzer.pageindex;

import com.tiance.demo.service.mysql.utils.ByteUtils;
import com.tiance.demo.service.mysql.bo.pageindex.IndexPageHeader;

public class IndexPageHeaderAnalyzer {

    public static String getHexStringOf(IndexPageHeader indexPageHeader) {
        byte[] bytes = indexPageHeader.getBytes();
        return ByteUtils.bytes2HexStr(bytes);
    }

    public static IndexPageHeader analyse(byte[] bytes) {
        IndexPageHeader indexPageHeader = new IndexPageHeader();
        indexPageHeader.setBytes(bytes);

        analyseNDirSlots(indexPageHeader);
        analyseHeapTop(indexPageHeader);
        analyseNHeap(indexPageHeader);
        analyseFree(indexPageHeader);
        analyseGarbage(indexPageHeader);
        analyseLastInsert(indexPageHeader);
        analyseDirection(indexPageHeader);
        analyseNDirection(indexPageHeader);
        analyseNRecs(indexPageHeader);
        analyseMaxTrxId(indexPageHeader);
        analyseLevel(indexPageHeader);
        analyseIndexId(indexPageHeader);
        analyseBtrSegLeaf(indexPageHeader);
        analyseBtrSegTop(indexPageHeader);

        return indexPageHeader;
    }

    private static void analyseNDirSlots(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 0, bytes, 0, 2);

        int nDirSlots = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setnDirSlots(nDirSlots);
    }

    private static void analyseHeapTop(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 2, bytes, 0, 2);

        int heapTop = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setHeapTop(heapTop);
    }

    private static void analyseNHeap(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 4, bytes, 0, 2);

        //第一个字节有特殊意义, 只有第二个字节是记录的具体数量
        byte[] validBytes = new byte[1];
        System.arraycopy(bytes, 1, validBytes, 0, 1);

        int nHeap = ByteUtils.bytes2Int(validBytes);
        indexPageHeader.setnHeap(nHeap);
    }

    private static void analyseFree(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 6, bytes, 0, 2);

        int free = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setFree(free);
    }

    private static void analyseGarbage(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 8, bytes, 0, 2);

        int garbage = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setGarbage(garbage);
    }

    private static void analyseLastInsert(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 10, bytes, 0, 2);

        int lastInsert = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setLastInsert(lastInsert);
    }

    private static void analyseDirection(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 12, bytes, 0, 2);

        int direction = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setDirection(direction);
    }

    private static void analyseNDirection(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 14, bytes, 0, 2);

        int nDirection = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setnDirection(nDirection);
    }

    private static void analyseNRecs(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 16, bytes, 0, 2);

        int nRecs = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setnRecs(nRecs);
    }

    private static void analyseMaxTrxId(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[8];
        System.arraycopy(indexPageHeader.getBytes(), 18, bytes, 0, 8);

        String maxTrxId = ByteUtils.bytes2HexStr(bytes);
        indexPageHeader.setMaxTransactionId(maxTrxId);
    }

    private static void analyseLevel(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[2];
        System.arraycopy(indexPageHeader.getBytes(), 26, bytes, 0, 2);

        int level = ByteUtils.bytes2Int(bytes);
        indexPageHeader.setLevel(level);
    }

    private static void analyseIndexId(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[8];
        System.arraycopy(indexPageHeader.getBytes(), 28, bytes, 0, 8);

        String indexId = ByteUtils.bytes2HexStr(bytes);
        indexPageHeader.setIndexId(indexId);
    }

    private static void analyseBtrSegLeaf(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[10];
        System.arraycopy(indexPageHeader.getBytes(), 36, bytes, 0, 10);

        String btrSegLeaf = ByteUtils.bytes2HexStr(bytes);
        indexPageHeader.setBtrSegleaf(btrSegLeaf);
    }

    private static void analyseBtrSegTop(IndexPageHeader indexPageHeader) {
        byte[] bytes = new byte[10];
        System.arraycopy(indexPageHeader.getBytes(), 46, bytes, 0, 10);

        String btrSegTop = ByteUtils.bytes2HexStr(bytes);
        indexPageHeader.setBtrSegTop(btrSegTop);
    }

}
